El entorno más cómodo para utilizar el lenguaje R es el programa R studio
Rstudio es una empresa que produce productos asociados al lenguaje R, como el programa sobre el que corremos los comandos, y extensiones del lenguaje (librerías).
El programa es gratuito y se puede bajar de la página oficial
Pantalla Rstudio
El operador <- sirve para definir un elemento. A la izquierda del <- debe ubicarse el nombre que tomará el elemento a crear. Del lado derecho debe ir la definición del mismo
A <- 1
Al definir un elemento, el mismo queda guardado en el ambiente del programa, y podrá ser utilizado posteriormente para observar su contenido o para realizar una operación con el mismo
A
[1] 1
Al correr una linea con el nombre del objeto, la consola del programa nos muestra su contenido. Entre Corchetes Observamos el número de orden del elemento en cuestión
El operador = es equivalente a <-, pero en la práctica no se utiliza para la definición de objetos.
B = 2
B
[1] 2
<- es un operador Unidireccional, es decir que:
A <- B implica que A va tomar como valor el contenido del objeto B, y no al revés.
A <- B
A #Ahora A toma el valor de B, y B continua conservando el mismo valor
[1] 2
B
[1] 2
Con R base nos referimos a los comandos básicos que vienen incorporados en el R, sin necesidad de cargar librerías.
A = 1
B = 2
A > B
[1] FALSE
A >= B
[1] FALSE
A < B
[1] TRUE
A <= B
[1] TRUE
A == B
[1] FALSE
A != B
[1] TRUE
C <- A != B
C
[1] TRUE
Como muestra el último ejemplo, el resultado de una operación lógica puede almacenarse como el valor de un objeto.
#suma
A <- 5+6
A
[1] 11
#Resta
B <- 6-8
B
[1] -2
#cociente
C <- 6/2.5
C
[1] 2.4
#multiplicacion
D <- 6*2.5
D
[1] 15
El numeral # se utiliza para hacer comentarios. Todo lo que se escribe después del # no es interpretado por R. Se debe utilizar un # por cada línea de código que se desea anular
[] se utilizan para acceder a un objeto:
el signo $ también es un método de acceso, que permite llamar al elemento por su nombre, en dataframes y listas.
Los paréntesis() se utilizan en las funciones para definir los parámetros.
Las comas , se utilizan para separar los elementos.
Ejemplo: si queremos definir al elemento de la fila 2 y columna 3 de una tabla como el resultado de una funcion con parámetros A=a, B=b y C=c, diremos:
tabla[2,3] <- funcion(A=a, B=b, C=c)
Los valores tienen distintos tipos:
Numeric
A <- 1
class(A)
[1] "numeric"
Character
A <- paste('Soy', 'una', 'concatenación', 'de', 'caracteres', sep = " ")
A
[1] "Soy una concatenación de caracteres"
class(A)
[1] "character"
Factor
A <- factor("Soy un factor, con niveles fijos")
class(A)
[1] "factor"
La diferencia entre un character y un factor es que el último tiene solo algunos valores permitidos (levels), y se le puede dar un orden
Date
A <- as.Date("2017-01-01")
class(A)
[1] "Date"
Para crear un vector utilizamos el comando c(), de combinar. Puede tener variables de cualquier tipo
C <- c(1, 3, 4)
C
[1] 1 3 4
sumarle 2 a cada elemento del vector anterior
C <- C + 2
C
[1] 3 5 6
sumarle 1 al primer elemento, 2 al segundo, y 3 al tercer elemento del vector anterior
D <- C + 1:3 #esto es equivalente a hacer 3+1, 5+2, 6+9
D
[1] 4 7 9
1:3 significa que queremos todos los números enteros desde 1 hasta 3.
crear un vector que contenga las palabras: Ingreso, Variación, Indice
E <- c("Carlos","Federico","Pedro")
E
[1] "Carlos" "Federico" "Pedro"
para acceder a algún elemento del vector, podemos buscarlo por su número de orden, entre [ ]
elemento2 <- E[2]
elemento2
[1] "Federico"
para borrar un objeto, utilizamos el comando rm()
rm(elemento2)
elemento2
Error: object 'elemento2' not found
También podemos cambiar el texto del segundo elemento de E, por el texto “var”
E[2] <- "Pablo"
E
[1] "Carlos" "Pablo" "Pedro"
Un Data Frame es una tabla de datos, donde cada columna representa una variable, y cada fila una observación. Son el equivalente a las tablas de STATA y SPSS
Este objeto suele ser central en el proceso de trabajo, y suele ser la forma en que se cargan datos externos, así como la mayoría de los elementos intermedios, hasta aquello que exportemos
También Se puede crear como la combinación de N vectores de igual tamaño. Por ejemplo, tomamos algunos valores del Indice de salarios
INDICE <- c(100, 100, 100,
101.8, 101.2, 100.73,
102.9, 102.4, 103.2)
FECHA <- c("Oct-16", "Oct-16", "Oct-16",
"Nov-16", "Nov-16", "Nov-16",
"Dic-16", "Dic-16", "Dic-16")
GRUPO <- c("Privado_Registrado","Público","Privado_No_Registrado",
"Privado_Registrado","Público","Privado_No_Registrado",
"Privado_Registrado","Público","Privado_No_Registrado")
Datos <- data.frame(INDICE, FECHA, GRUPO)
Datos
Tal como en un vector se ubica a los elementos mediante [ ], en un dataframe se obtienen sus elementos de la forma [fila, columna].
Otra opción es seleccionar la columna, mediante el operador $, y luego seleccionar dentro de esa columna, por el número de orden.
Datos$FECHA
[1] Oct-16 Oct-16 Oct-16 Nov-16 Nov-16 Nov-16 Dic-16 Dic-16 Dic-16
Levels: Dic-16 Nov-16 Oct-16
Datos[3,2]
[1] Oct-16
Levels: Dic-16 Nov-16 Oct-16
Datos$FECHA[3]
[1] Oct-16
Levels: Dic-16 Nov-16 Oct-16
¿que pasa si hacemos Datos$FECHA[3,2] ?
Datos$FECHA[3,2]
Error in `[.default`(Datos$FECHA, 3, 2) : incorrect number of dimensions
Nótese que el último comando tiene un número incorrecto de dimensiones, porque estamos refiriendonos 2 veces a la columna FECHA.
Contienen una concatenación de objetos de cualquier tipo. Así como un vector contiene valores, un dataframe contiene vectores, una lista puede contener dataframes, pero también vectores, o valores, y todo ello a la vez
superlista <- list(A,B,C,D,E,FECHA, DF = Datos, INDICE, GRUPO)
superlista
[[1]]
[1] "2017-01-01"
[[2]]
[1] -2
[[3]]
[1] 3 5 6
[[4]]
[1] 4 7 9
[[5]]
[1] "Carlos" "Pablo" "Pedro"
[[6]]
[1] "Oct-16" "Oct-16" "Oct-16" "Nov-16" "Nov-16" "Nov-16" "Dic-16" "Dic-16"
[9] "Dic-16"
$DF
[[8]]
[1] 100.00 100.00 100.00 101.80 101.20 100.73 102.90 102.40 103.20
[[9]]
[1] "Privado_Registrado" "Público" "Privado_No_Registrado"
[4] "Privado_Registrado" "Público" "Privado_No_Registrado"
[7] "Privado_Registrado" "Público" "Privado_No_Registrado"
Para acceder un elemento de una lista, podemos utilizar el operador $, que se puede usar a su vez de forma iterativa
superlista$DF$FECHA[2]
[1] Oct-16
Levels: Dic-16 Nov-16 Oct-16
Un loop es una estructura de código que nos permite recorrer iterativamente un conjunto de comandos, variando algún elemento. Por ejemplo:
for(i in 1:10){
Cuadrados<- i^2
print(Cuadrados)
}
[1] 1
[1] 4
[1] 9
[1] 16
[1] 25
[1] 36
[1] 49
[1] 64
[1] 81
[1] 100
esto se lee como : Para i, que toma los valores de 1 a 10: imprimí i.
También se puede tomar una lista de valores cualesquiera. Por ejemplo reutilizar datos de un dataframe:
Datos
unique(Datos$GRUPO)
[1] Privado_Registrado Público Privado_No_Registrado
Levels: Privado_No_Registrado Privado_Registrado Público
for(variable in unique(Datos$GRUPO)){
print(Datos[Datos$GRUPO == variable,])
}
Las estructuras condiconales nos permites ejecutar código de forma condicional a que se cumpla determinada condición.
A
[1] "2017-01-01"
resultado <- ifelse(test = class(A) == "character", yes = paste0("Esto es un caracter"),
no = paste0("Esto no era un caracter"))
resultado
[1] "Esto no era un caracter"
Otra función para condicionar la ejecución de una porción del código es if(condicion){codigo a ejecutar si se cumple la condición}
Las funciones nos permiten automatizar todas aquellas partes del código que se repiten mucho. Una vez diseñadas, funcionan igual que cualquier comando. La facilidad para crear las funciones es en buena medida la explicación de que haya tantas contribuciones de usuarios a la expansión del lenguaje.
funcion_prueba <- function(a,b) {
print(paste(a, b, sep = " "))
}
funcion_prueba(a = "soy la primera parte de un string.", b = "Y yo la segunda parte")
[1] "soy la primera parte de un string. Y yo la segunda parte"
También podemos asignar un valor por default.
funcion_prueba <- function(a = "Soy una primera parte default.",b) {
print(paste(a, b, sep = " "))
}
funcion_prueba(b = " A mi no me defaulteas")
[1] "Soy una primera parte default. A mi no me defaulteas"
Las funciones que creamos nosotros viven dentro del script donde se las define. Es decir, es necesario volver a correr la definición cada vez que la queremos utilizar.
Vale mencionar que lo que ocurre en una función, queda en la función excepto que explícitamente pidamos que devuelva el resultado, con el comando print() o return()
R tiene formatos de archivos propios:
x <- 1:15
y <- list(a = 1, b = TRUE, c = "oops")
#Para guardar
save(x, y, file = "xy.RData")
#Para leer
load('xy.RData')
Los archivos de tipo RData permiten grabar una imagen de todos los objetos R que querramos.
x
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
saveRDS(x, "x.RDS")
Z <- readRDS("x.RDS")
Z
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Los archivos de tipo RDS no guardan el nombre del objeto, por lo que podemos nombrarlos cuando los cargamos (aconsejable)
Hay muchas funciones para leer archivos de tipo .txt y .csv. La mayoría sólo cambia los parámetros que vienen por default.
Es importante tener en cuenta:
,, tab, ;)dataframe <- read.delim(file, header = TRUE, sep = "\t", quote = "\"", dec = ".", fill = TRUE, comment.char = "", ...)
Ejemplo. Levantar la base individual de EPH del 1er trimestre 2017
individual_t117 <- read.table('//NE18106/Trabajos/Curso R/Fuentes/usu_individual_t117.txt',sep=";", dec=",", header = TRUE, fill = TRUE)
individual_t117
aprovechemos esta primera tabla en serio para introducir algunos comandos útiles para tener una mirada rápida de la base.
#View(individual_t117)
names(individual_t117)
[1] "CODUSU" "ANO4" "TRIMESTRE" "NRO_HOGAR" "COMPONENTE" "H15"
[7] "REGION" "MAS_500" "AGLOMERADO" "PONDERA" "CH03" "CH04"
[13] "CH05" "CH06" "CH07" "CH08" "CH09" "CH10"
[19] "CH11" "CH12" "CH13" "CH14" "CH15" "CH15_COD"
[25] "CH16" "CH16_COD" "NIVEL_ED" "ESTADO" "CAT_OCUP" "CAT_INAC"
[31] "IMPUTA" "PP02C1" "PP02C2" "PP02C3" "PP02C4" "PP02C5"
[37] "PP02C6" "PP02C7" "PP02C8" "PP02E" "PP02H" "PP02I"
[43] "PP03C" "PP03D" "PP3E_TOT" "PP3F_TOT" "PP03G" "PP03H"
[49] "PP03I" "PP03J" "INTENSI" "PP04A" "PP04B_COD" "PP04B1"
[55] "PP04B2" "PP04B3_MES" "PP04B3_ANO" "PP04B3_DIA" "PP04C" "PP04C99"
[61] "PP04D_COD" "PP04G" "PP05B2_MES" "PP05B2_ANO" "PP05B2_DIA" "PP05C_1"
[67] "PP05C_2" "PP05C_3" "PP05E" "PP05F" "PP05H" "PP06A"
[73] "PP06C" "PP06D" "PP06E" "PP06H" "PP07A" "PP07C"
[79] "PP07D" "PP07E" "PP07F1" "PP07F2" "PP07F3" "PP07F4"
[85] "PP07F5" "PP07G1" "PP07G2" "PP07G3" "PP07G4" "PP07G_59"
[91] "PP07H" "PP07I" "PP07J" "PP07K" "PP08D1" "PP08D4"
[97] "PP08F1" "PP08F2" "PP08J1" "PP08J2" "PP08J3" "PP09A"
[103] "PP09A_ESP" "PP09B" "PP09C" "PP09C_ESP" "PP10A" "PP10C"
[109] "PP10D" "PP10E" "PP11A" "PP11B_COD" "PP11B1" "PP11B2_MES"
[115] "PP11B2_ANO" "PP11B2_DIA" "PP11C" "PP11C99" "PP11D_COD" "PP11G_ANO"
[121] "PP11G_MES" "PP11G_DIA" "PP11L" "PP11L1" "PP11M" "PP11N"
[127] "PP11O" "PP11P" "PP11Q" "PP11R" "PP11S" "PP11T"
[133] "P21" "DECOCUR" "IDECOCUR" "RDECOCUR" "GDECOCUR" "PDECOCUR"
[139] "ADECOCUR" "PONDIIO" "TOT_P12" "P47T" "DECINDR" "IDECINDR"
[145] "RDECINDR" "GDECINDR" "PDECINDR" "ADECINDR" "PONDII" "V2_M"
[151] "V3_M" "V4_M" "V5_M" "V8_M" "V9_M" "V10_M"
[157] "V11_M" "V12_M" "V18_M" "V19_AM" "V21_M" "T_VI"
[163] "ITF" "DECIFR" "IDECIFR" "RDECIFR" "GDECIFR" "PDECIFR"
[169] "ADECIFR" "IPCF" "DECCFR" "IDECCFR" "RDECCFR" "GDECCFR"
[175] "PDECCFR" "ADECCFR" "PONDIH"
summary(individual_t117)[,c(8,10,31,133)]
MAS_500 PONDERA IMPUTA P21
N:31790 Min. : 25.0 Min. :0.000000 Min. : -9
S:26885 1st Qu.: 137.0 1st Qu.:0.000000 1st Qu.: 0
Median : 238.0 Median :0.000000 Median : 0
Mean : 467.3 Mean :0.002727 Mean : 3671
3rd Qu.: 541.0 3rd Qu.:0.000000 3rd Qu.: 4800
Max. :7001.0 Max. :1.000000 Max. :300000
head(individual_t117)[,1:5]
Para leer archivos excel debemos utilizar los comandos que vienen con la librería xlsx
# install.packages("xlsx") # por única vez
library(xlsx) #activamos la librería
#creamos una tabla cualquiera de prueba
x <- 1:10
y <- 11:20
tabla_de_R <- data.frame(x,y)
# escribimos el archivo
write.xlsx( x = tabla_de_R, file = "archivo.xlsx",sheetName = "hoja 1",row.names = FALSE)
#leemos el archivo
tabla <- read.xlsx(file = "archivo.xlsx",sheetName = "hoja 1")
tabla
Podemos utilizar la librería haven, y los comandos:
Tanto a la hora de leer y escribir archivos, como al trabajar un mismo script desde distintas computadoras, debemos ser cuidadosos con el encoding seteado. El encoding es el sistema mediante el cual el sistema interpreta los caracteres del lenguaje natural. Hay muchos encodings diferentes, que interpretan distinto algunos caracteres, como tildes y signos de puntuación.
Por ende, si el encoding seteado no es el mismo que el de nuestro script/tabla pueden generarse errores. En medida de lo posible, al escribir nuestros scripts es recomendable evitar estos caracteres.
R tiene por default el encoding “ISO-8859-1”, sin embargo el más habitual en América Latina es “UTF-8”.
Siempre que escribimos el nombre del archivo, R lo busca en el working directory. Para saber cual es el directorio de trabajo utilizamos la función getwd(). Para redefinir el directorio de trabajo, utilizamos la función setwd
No es aconsejable utilizar el directorio de trabajo, si nos olvidamos de definirlo, tiramos los archivos en cualquier lado
Lo más práctico es definir los directorios de trabajo como valores. y pegar el nombre del archivo con las carpetas.
carpeta_fuentes <- paste("C:/Users/.../Documents/R/fuentes/")
carpeta_resultados <- paste("C:/Users/.../Documents/R/resultados/")
Es importante notar que se utiliza la barra / en lugar de \ (que sale de copiar y pegar el directorio)
el nombre completo del archivo puede ser
archivo_datos <- paste0(carpeta_fuentes, "archivo_fuentes.txt")
archivo_resultados <- paste0(carpeta_resultados, "archivo_resultados.txt")
luego, para leer un excel, se escribe:
tabla <- read.xlsx(file = archivo_datos,sheetName = "hoja 1") #como es una variable, ya no lleva comillas
Si bien excede los alcances de este curso, dejamos un chunk de código que puede resultar sumamente útil para crear un directorio de trabajo para un proyecto nuevo.
#install.packages(rstudioapi)
script.dir <- paste0(dirname(rstudioapi::getActiveDocumentContext()$path),"/")
bases.dir <- paste0(dirname(script.dir),"/Fuentes/")
#dir.create(bases.dir)
resultados.dir <- paste0(dirname(script.dir),"/Resultados/")
#dir.create(resultados.dir)
#chequeo
dir.exists(bases.dir)
[1] TRUE
dir.exists(resultados.dir)
[1] TRUE
La primera línea encuentra la carpeta donde esta guardado el script (si no esta guardado no funciona).
La segunda línea crea el nombre del directorio Fuentes La tercera línea (anulada) crea el directorio Fuentes La cuarta línea crea el nombre del directorio Resultados La quinta línea (anulada) crea el directorio Resultados
Por último, es aconsejable mantener en todos los script una misma estructura del tipo:
rm(list=ls())También es útil organizar las partes del script en capítulos. Para eso
### escribimos el título del capitulo encerrado entre tres o más corchetes ###
Hay muchas ayudas, propias del programa, o de usuarios, que pueden ser de ayuda.
En el programa, para consultar los parámetros de una función, le escribe ?funcion()
Rstudio tiene unos machetes muy útiles
stack overflow conviene llegar desde google
La clave es aprender la terminología para googlear en ingles las dudas, y prestar atención a que las respuestas sean actuales (R es un lenguaje vivo)
instalar los siguientes paquetes:
install.packages(c("tidyverse","xlsx",'statar','reldist', 'ggthemes', 'ggrepel', 'scales', 'ggjoy', 'rstudioapi','questionr', 'alluvial'))
Crear una lista con cada uno de los elementos creados previamente
Crear una función que devuelva la sumatoria de los números enteros comprendidos entre 1 y un parámetro x a definir
dir.exist() que lo creamos bien (¿no funcionó? pista: /\)Ejecutar los siguientes comandos:
install.packages(rstudioapi) # SOLO LA PRIMERA VEZ
script.dir <- paste0(dirname(rstudioapi::getActiveDocumentContext()$path),"/")
script.dir
bases.dir <- paste0(dirname(script.dir),"/Fuentes/")
bases.dir
dir.create(bases.dir)
resultados.dir <- paste0(dirname(script.dir),"/Resultados/")
resultados.dir
dir.create(resultados.dir)
dir.exists(bases.dir)
¿qué sucedió? Explicar que realiza cada una de las líneas.